/*
Copyright (C) 2022-2024 Inspur Corp.

SPDX-License-Identifier: Apache-2.0
*/
package service

import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/avast/retry-go"
	"github.com/pkg/errors"
	"github.com/tidwall/gjson"
	"github.com/tjfoc/gmsm/sm3"
	"icep/bean/entity"
	"icep/bean/model"
	"icep/bean/param"
	"icep/chain/client"
	chm "icep/chain/model"
	"icep/common/constant"
	"icep/common/crypto/gm"
	"icep/common/db"
	"icep/common/file"
	"icep/common/upload"
	"icep/common/utils"
	uuid2 "icep/common/uuid"
	"io"
	"mime/multipart"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
)

func (is *IcepService) GetFileEvidencePage(userId, evidenceName, evidenceType, useEncrypt, startTime, endTime string, pageSize, pageNo int) (*db.Page, error) {
	args := make([]interface{}, 0)
	ccQuery := utils.StrJoin("user_id = ?")
	args = append(args, userId)

	if len(evidenceName) > 0 {
		ccQuery = utils.StrJoin(ccQuery, " and evidence_name like concat('%', ?::varchar, '%') escape '/'")
		ccArg := strings.Replace(evidenceName, "%", "/%", -1)
		ccArg = strings.Replace(ccArg, "_", "/_", -1)
		args = append(args, ccArg)
	}
	if len(useEncrypt) > 0 {
		ccQuery += " and use_encrypt = ?"
		args = append(args, useEncrypt)
	}
	if len(evidenceType) > 0 {
		ccQuery += " and evidence_type = ?"
		args = append(args, evidenceType)
	}
	if startTime != "" {
		ccQuery += " and created_time >= ?"
		args = append(args, startTime)
	}
	if endTime != "" {
		ccQuery += " and created_time <= ?"
		args = append(args, endTime)
	}
	page := db.NewPage(0, pageNo).SetPageSize(pageSize)

	var countEntity entity.IcepFileEvidence
	count, err := is.DbEngine.Where(ccQuery, args...).Count(&countEntity)
	if err != nil {
		log.Errorf("query fileEvidence list count error: %s", err)
		return nil, err
	}
	page.SetTotal(count)

	fileEvidenceList := make([]*entity.IcepFileEvidence, 0)
	err = is.DbEngine.Where(ccQuery, args...).Limit(pageSize, (pageNo-1)*pageSize).Desc("updated_time").Find(&fileEvidenceList)
	if err != nil {
		log.Errorf("query func GeFileEvidencePage error: %s", err)
		return nil, err
	}
	fileEDetailList := make([]*model.FileEvidenceDetail, 0)
	for _, fileE := range fileEvidenceList {
		fileEDetailList = append(fileEDetailList, &model.FileEvidenceDetail{
			EvidenceId:   fileE.Id,
			UserId:       fileE.UserId,
			IdentityId:   fileE.IdentityId,
			EvidenceName: fileE.EvidenceName,
			EvidenceType: fileE.EvidenceType,
			UseEncrypt:   fileE.UseEncrypt,
			Status:       fileE.Status,
			TxId:         fileE.TxId,
			TxTime:       fileE.TxTime,
			CreatedTime:  fileE.CreatedTime.Format(constant.TimeLayout),
			UpdatedTime:  fileE.UpdatedTime.Format(constant.TimeLayout),
		})
	}
	page.CreatePage(fileEDetailList)
	return page, err
}

func (is *IcepService) GetFileEvidenceList(userId string, evidenceParam param.FileEvidenceParam) ([]*entity.IcepFileEvidence, error) {
	fileEvidenceList := make([]*entity.IcepFileEvidence, 0)
	err := is.DbEngine.Where("evidence_name = ? ", evidenceParam.EvidenceName).Desc("updated_time").Find(&fileEvidenceList)
	if err != nil {
		log.Errorf("query func GetFileEvidenceList error: %s", err)
		return nil, err
	}
	return fileEvidenceList, err
}

func (is *IcepService) GetFileEvidenceInfo(userId, tenantId string, evidenceId string) (*model.FileEvidenceInfo, error) {
	fileEvidence := new(entity.IcepFileEvidence)
	has, err := is.DbEngine.Where("id = ? and user_id = ?", evidenceId, userId).Get(fileEvidence)
	if err != nil {
		log.Errorf("存证编号%s查询异常 %v", evidenceId, err)
		return nil, err
	}
	fileInfos := make([]model.FileInfo, 0)
	err = is.DbEngine.SQL(
		"select file_name as name, file_url as url, file_hash as hash from icep_file_evidence_detail where evidence_id = ?", evidenceId).Find(&fileInfos)
	if err != nil {
		log.Errorf("存证编号%s查询文件详情异常 %v", evidenceId, err)
		return nil, err
	}
	fileEvidenceInfo := &model.FileEvidenceInfo{
		EvidenceId:   fileEvidence.Id,
		EvidenceName: fileEvidence.EvidenceName,
		EvidenceType: fileEvidence.EvidenceType,
		UseEncrypt:   fileEvidence.UseEncrypt,
		Status:       fileEvidence.Status,
		EvidenceCert: fileEvidence.EvidenceCert,
		TxId:         fileEvidence.TxId,
		TxTime:       fileEvidence.TxTime,
		FileInfo:     fileInfos,
	}
	if has {
		//get data by chain txid
		client := is.GetChainClient(tenantId)
		blockInfo := client.GetBlockInfoById(fileEvidence.TxId)
		txInfo := client.GetTransactionInfoById(fileEvidence.TxId)
		log.Infof("%s's blockinfo is: %v ----- txinfo is :%v ", fileEvidence.TxId, blockInfo, txInfo)
		txContent := new(chm.WriteModel)
		json.Unmarshal([]byte(txInfo.TxContent), txContent)
		chainData := new(model.ChainFileEvidence)
		json.Unmarshal([]byte(txContent.Value), chainData)

		fileEvidenceInfo.BlockNum = fmt.Sprintf("%d", blockInfo.BlockNum)
		fileEvidenceInfo.BlockHash = blockInfo.BlockHash
		fileEvidenceInfo.TxContent = txInfo.TxContent
		fileEvidenceInfo.EvidenceData = chainData.EvidenceData
		fileEvidenceInfo.Signature = chainData.Sign
		fileEvidenceInfo.PubKey = chainData.PubKey

		return fileEvidenceInfo, err
	}
	return fileEvidenceInfo, nil
}

func (is *IcepService) CreateFileEvidence(userId string, fep param.FileEvidenceParam, files []*multipart.FileHeader) error {
	user, result := is.GetUserByUserId(userId)
	if !result {
		log.Errorf("%v 用户信息获取失败", userId)
		return errors.New("用户信息获取失败")
	}
	evidenceId := uuid2.GenerateAlphaWithPrefix("fE")
	userPrvK := gm.DecryptPrvKey(user.PrvKey)
	identity, result := is.GetIdentityByTenantId(user.TenantId)
	if !result {
		log.Errorf("%v 用户的区块链身份获取失败", userId)
		return errors.New("用户的区块链身份获取失败")
	}

	//对称秘钥记录处理
	sm4Key := gm.GenerateSm4Key()
	if fep.UseEncrypt == "1" {
		sm4KeyBytes, _ := hex.DecodeString(sm4Key)
		encrytSecret := gm.EncryptByPubKey(user.PubKey, sm4KeyBytes)
		icepSecret := entity.IcepSecret{
			Id:            uuid2.GenerateAlpha(),
			EvidenceId:    evidenceId,
			UserId:        userId,
			EncryptSecret: encrytSecret,
			CreatedTime:   time.Now(),
			UpdatedTime:   time.Now(),
		}
		_, err := is.DbEngine.InsertOne(&icepSecret)
		if err != nil {
			log.Error("对称秘钥记录插入异常")
			return err
		}
	}

	//文件存证记录处理
	fileEvidence := entity.IcepFileEvidence{
		Id:           evidenceId,
		UserId:       user.Id,
		IdentityId:   identity.IdentityId,
		EvidenceName: fep.EvidenceName,
		EvidenceType: fep.EvidenceType,
		UseEncrypt:   fep.UseEncrypt,
		Status:       "0",
		TxId:         "",
		TxTime:       "",
		CreatedTime:  time.Now(),
		UpdatedTime:  time.Now(),
	}
	_, err := is.DbEngine.InsertOne(&fileEvidence)
	if err != nil {
		log.Error("数据存证记录插入异常")
		return err
	}

	_, fileHashs, err := FileHandle(files, is, evidenceId, fep.UseEncrypt, sm4Key)
	if err != nil {
		return err
	}
	hashs := utils.HashArrayToHash(fileHashs)
	signData := []byte(hashs)
	//record signature
	icepSignature := entity.IcepSignature{
		Id:          uuid2.GenerateAlpha(),
		EvidenceId:  evidenceId,
		Signature:   "",
		CreatedTime: time.Now(),
		UpdatedTime: time.Now(),
	}
	icepSignature.Signature = gm.Sign(userPrvK, signData)
	_, err = is.DbEngine.InsertOne(&icepSignature)
	if err != nil {
		log.Error("签名记录插入异常")
		return err
	}

	//线程判断存证是否成功
	client := is.GetChainClient(user.TenantId)

	putValue := map[string]string{
		"userId":       user.Id,
		"pubKey":       user.PubKey,
		"sign":         icepSignature.Signature,
		"evidenceData": string(signData),
	}

	value, err := json.MarshalIndent(putValue, "", " ")
	if err != nil {
		log.Errorf("上链数据格式异常： %v", err)
		return err
	}
	go is.fileEvidenceToChain(client, fileEvidence, string(value), hashs)

	return err
}

func (is *IcepService) GetDepositoryLetterParam(userId string) *param.EvidenceLetterParam {
	user, result := is.GetUserByUserId(userId)
	if !result {
		log.Errorf("%v 用户信息获取失败", userId)
		return nil
	}
	subject := user.Id
	subjectId := user.Id
	if user.UserType == constant.UserTypePerson {
		person, err := is.GetRealNamePerson(user.Id)
		if err != nil {
			log.Errorf("get real name person error: %v", err)
			person = nil
		}
		if person != nil {
			subject = person.PersonName
			subjectId = person.PersonId
		}
	} else if user.UserType == constant.UserTypeOrg {
		org, err := is.GetRealNameOrg(user.Id)
		if err != nil {
			log.Errorf("get real name org error: %v", err)
			org = nil
		}
		if org != nil {
			subject = org.OrgName
			subjectId = org.OrgCode
		}
	}

	letterParam := &param.EvidenceLetterParam{
		EvidenceSubject:   subject,
		SubjectId:         subjectId,
		EvidencePlatform:  "可信存取证平台",
		OperationsSubject: "OpenIBC",
	}
	return letterParam
}

//非秘钥托管类文件存证接口
func (is *IcepService) CreateFileNokeyEvidence(userId string, param param.FileEvidenceParam, files []*multipart.FileHeader) error {
	//todo
	user, result := is.GetUserByUserId(userId)
	if !result {
		log.Errorf("%v 用户信息获取失败", userId)
		return errors.New("用户信息获取失败")
	}
	evidenceId := uuid2.GenerateAlphaWithPrefix("fE")
	userPrvK := gm.DecryptPrvKey(user.PrvKey)
	identity, result := is.GetIdentityByTenantId(user.TenantId)
	if !result {
		log.Errorf("%v 用户的区块链身份获取失败", userId)
		return errors.New("用户的区块链身份获取失败")
	}

	//对称秘钥记录处理 - 文件存证
	if param.UseEncrypt == "1" && param.EvidenceType != "0" {
		icepSecret := entity.IcepSecret{
			Id:            uuid2.GenerateAlpha(),
			EvidenceId:    evidenceId,
			UserId:        userId,
			EncryptSecret: param.EncryptedSecret,
			CreatedTime:   time.Now(),
			UpdatedTime:   time.Now(),
		}
		_, err := is.DbEngine.InsertOne(&icepSecret)
		if err != nil {
			log.Error("对称秘钥记录插入异常")
			return err
		}
	}

	//文件存证记录处理
	fileEvidence := entity.IcepFileEvidence{
		Id:           evidenceId,
		UserId:       user.Id,
		IdentityId:   identity.IdentityId,
		EvidenceName: param.EvidenceName,
		EvidenceType: param.EvidenceType,
		UseEncrypt:   param.UseEncrypt,
		Status:       "0",
		TxId:         "",
		TxTime:       "",
		CreatedTime:  time.Now(),
		UpdatedTime:  time.Now(),
	}
	_, err := is.DbEngine.InsertOne(&fileEvidence)
	if err != nil {
		log.Error("数据存证记录插入异常")
		return err
	}
	var signData []byte
	if param.EvidenceType == "0" {
		fileHashs := make([]string, 0)
		for _, hashFile := range param.FileInfo {
			icepFileEvidenceDetail := entity.IcepFileEvidenceDetail{
				Id:          uuid2.GenerateAlpha(),
				EvidenceId:  evidenceId,
				FileName:    hashFile.Name,
				FileHash:    hashFile.Hash,
				FileUrl:     hashFile.Url,
				CreatedTime: time.Now(),
				UpdatedTime: time.Now(),
			}
			_, err = is.DbEngine.InsertOne(&icepFileEvidenceDetail)
			if err != nil {
				log.Error(hashFile.Name + "文件详情插入异常")
				return err
			}
			fileHashs = append(fileHashs, hashFile.Hash)
		}
		sort.Strings(fileHashs)
		signData = []byte(utils.HashArrayToHash(fileHashs))
	} else {
		_, fileHashs, err := FileHandle(files, is, evidenceId, param.UseEncrypt, "")
		if err != nil {
			return err
		}
		signData = []byte(utils.HashArrayToHash(fileHashs))
	}
	//record signature
	icepSignature := entity.IcepSignature{
		Id:          uuid2.GenerateAlpha(),
		EvidenceId:  evidenceId,
		Signature:   "",
		CreatedTime: time.Now(),
		UpdatedTime: time.Now(),
	}
	icepSignature.Signature = gm.Sign(userPrvK, signData)
	_, err = is.DbEngine.InsertOne(&icepSignature)
	if err != nil {
		log.Error("签名记录插入异常")
		return err
	}

	//线程判断存证是否成功
	client := is.GetChainClient(user.TenantId)
	//evidenceDataBytes, _ := json.Marshal(chainData)
	putValue := map[string]string{
		"userId":       user.Id,
		"pubKey":       user.PubKey,
		"sign":         icepSignature.Signature,
		"evidenceData": string(signData),
	}

	value, err := json.MarshalIndent(putValue, "", " ")
	if err != nil {
		log.Errorf("上链数据格式异常： %v", err)
		return err
	}
	go is.fileEvidenceToChain(client, fileEvidence, string(value), string(signData))

	return err
}

//文件hash存证接口
func (is *IcepService) CreateFileHashEvidence(userId string, param param.FileEvidenceParam) error {
	user, result := is.GetUserByUserId(userId)
	if !result {
		log.Errorf("%v 用户信息获取失败", userId)
		return errors.New("用户信息获取失败")
	}
	evidenceId := uuid2.GenerateAlphaWithPrefix("hE")
	userPrvK := gm.DecryptPrvKey(user.PrvKey)
	identity, result := is.GetIdentityByTenantId(user.TenantId)
	if !result {
		log.Errorf("%v 用户的区块链身份获取失败", userId)
		return errors.New("用户的区块链身份获取失败")
	}

	//文件存证记录处理
	fileEvidence := entity.IcepFileEvidence{
		Id:           evidenceId,
		UserId:       user.Id,
		IdentityId:   identity.IdentityId,
		EvidenceName: param.EvidenceName,
		EvidenceType: "0",
		Status:       "0",
		TxId:         "",
		TxTime:       "",
		CreatedTime:  time.Now(),
		UpdatedTime:  time.Now(),
	}
	_, err := is.DbEngine.InsertOne(&fileEvidence)
	if err != nil {
		log.Error("数据存证记录插入异常")
		return err
	}
	fileHashs := make([]string, 0)
	for _, hashFile := range param.FileInfo {
		icepFileEvidenceDetail := entity.IcepFileEvidenceDetail{
			Id:          uuid2.GenerateAlpha(),
			EvidenceId:  evidenceId,
			FileName:    hashFile.Name,
			FileHash:    hashFile.Hash,
			FileUrl:     hashFile.Url,
			CreatedTime: time.Now(),
			UpdatedTime: time.Now(),
		}
		_, err = is.DbEngine.InsertOne(&icepFileEvidenceDetail)
		if err != nil {
			log.Error(hashFile.Name + "文件详情插入异常")
			return err
		}
		fileHashs = append(fileHashs, hashFile.Hash)
	}
	sort.Strings(fileHashs)
	signData := []byte(utils.HashArrayToHash(fileHashs))
	//record signature
	icepSignature := entity.IcepSignature{
		Id:          uuid2.GenerateAlpha(),
		EvidenceId:  evidenceId,
		Signature:   "",
		CreatedTime: time.Now(),
		UpdatedTime: time.Now(),
	}
	icepSignature.Signature = gm.Sign(userPrvK, signData)
	_, err = is.DbEngine.InsertOne(&icepSignature)
	if err != nil {
		log.Error("签名记录插入异常")
		return err
	}

	//线程判断存证是否成功
	client := is.GetChainClient(user.TenantId)

	putValue := map[string]string{
		"userId":       user.Id,
		"pubKey":       user.PubKey,
		"sign":         icepSignature.Signature,
		"evidenceData": string(signData),
	}

	value, err := json.MarshalIndent(putValue, "", " ")
	if err != nil {
		log.Errorf("上链数据格式异常： %v", err)
		return err
	}
	go is.fileEvidenceToChain(client, fileEvidence, string(value), string(signData))

	return err
}

func (is *IcepService) DecryptFileEvidence(userPrivateKey, evidenceId, fileUrl string) (string, string, bool) {
	decryptSecret := new(entity.IcepSecret)
	fileName := filepath.Base(fileUrl)
	result, _ := is.DbEngine.Where("evidence_id = ?", evidenceId).Get(decryptSecret)
	if result {
		fileEvidence := new(entity.IcepFileEvidence)
		result, _ = is.DbEngine.Where("id = ? and use_encrypt = '1' and evidence_type in ('1','2','3','4')", evidenceId).Get(fileEvidence)
		if !result {
			log.Errorf("该存证不支持解密")
			return "", "", false
		}
		sm4Key := gm.DecryptByPrvKey(gm.DecryptPrvKey(userPrivateKey), decryptSecret.EncryptSecret)
		if sm4Key != nil {
			//tempDir := "D:\\ichain"
			tempDir := os.TempDir()
			destPath := tempDir + constant.FileSeparator + "decrypt-" + evidenceId
			err := file.CreateIfNotExists(destPath, true)
			if err != nil {
				log.Errorf("创建文件失败 %v", err)
				return "", fileName, false
			}

			//获取oss文件
			downloadFile := destPath + constant.FileSeparator + "oss" + fileName
			destPath = destPath + constant.FileSeparator + fileName

			err = utils.Download(
				utils.DlFileInfo{
					Url:      fileUrl,
					Filename: downloadFile,
					Filemode: 0755,
					Strategy: 2, // 如果是小文件下载，1、2均可； 如果是大文件，推荐2
				})
			if err != nil {
				log.Errorf("decrypt oss download file failed: %v", err)
				return "", fileName, false
			}

			err = gm.Sm4DecryptFile(hex.EncodeToString(sm4Key), downloadFile, destPath)
			if err != nil {
				log.Errorf("解密文件失败 %v", err)
				return "", fileName, false
			}
			errs := file.DeleteFile(downloadFile)
			if errs != nil {
				log.Errorf("删除本地文件失败: %s", errs)
			}
			return destPath, fileName, true
		}
	}
	return "", fileName, false
}

func FileHandle(files []*multipart.FileHeader, is *IcepService, evidenceId, useEncrypt, sm4Key string) ([]model.FileInfo, []string, error) {
	tempDir := os.TempDir()
	//tempDir := "D:\\ichain"
	path := utils.StrJoin(tempDir, constant.FileSeparator, evidenceId, constant.FileSeparator)
	client := upload.GetUploadClient()
	fileInfos := make([]model.FileInfo, 0)
	fileHashs := make([]string, 0)

	for _, fileHeader := range files {
		fileName := fileHeader.Filename
		filePath := utils.StrJoin(path, fileName)
		file.CreateIfNotExists(filePath, false)
		err := file.SaveUploadedFile(fileHeader, filePath)
		if err != nil {
			log.Errorf("save uploaded file  %s error: %v", fileName, err)
			return nil, nil, err
		}
		if useEncrypt == "1" && sm4Key != "" {
			destPath := utils.StrJoin(path, "encrypt")
			file.CreateIfNotExists(destPath, true)
			destPath = destPath + constant.FileSeparator + fileName
			err := gm.Sm4EncryptFile(sm4Key, filePath, destPath)
			if err != nil {
				log.Errorf("Sm4EncryptFile  %s error: %v", fileName, err)
				return nil, nil, err
			}
			filePath = destPath
		}
		fileHash, _ := GetFileHash(filePath)
		fileurl, err := client.UploadFile(filePath, evidenceId+"/"+fileName)
		if err != nil {
			log.Errorf("oss uploaded file  %s error: %v", fileName, err)
			return nil, nil, err
		}
		errs := file.DeleteFileAll(path)
		if errs != nil {
			log.Errorf("删除本地文件失败: %s", errs)
		}
		log.Debugf("fileName = %s, fileurl = %s,fileHash = %s ", fileName, fileurl, fileHash)
		fileInfos = append(fileInfos, model.FileInfo{
			Name: fileName,
			Url:  fileurl,
			Hash: fileHash,
		})
		icepFileEvidenceDetail := entity.IcepFileEvidenceDetail{
			Id:          uuid2.GenerateAlpha(),
			EvidenceId:  evidenceId,
			FileName:    fileName,
			FileHash:    fileHash,
			FileUrl:     fileurl,
			CreatedTime: time.Now(),
			UpdatedTime: time.Now(),
		}
		_, err = is.DbEngine.InsertOne(&icepFileEvidenceDetail)
		if err != nil {
			log.Error(fileName + "文件详情插入异常")
			return nil, nil, err
		}
		fileHashs = append(fileHashs, fileHash)
	}
	sort.Strings(fileHashs)
	return fileInfos, fileHashs, nil
}

func GetFileHash(filePath string) (fileHash string, err error) {
	hash := sm3.New()
	fileReader, err := os.Open(filePath)
	fileName := fileReader.Name()
	if err != nil {
		log.Errorf(" file %s open error: %v", fileName, err)
		return "", err
	}
	defer fileReader.Close()
	if _, err := io.Copy(hash, fileReader); err != nil {
		log.Errorf("get file %s hash error: %v", fileName, err)
		return "", err
	}
	hashBytes := hash.Sum(nil)
	return hex.EncodeToString(hashBytes), err
}

func (is *IcepService) fileEvidenceToChain(client *client.IchainClient, fileEvidence entity.IcepFileEvidence, putValue string, hashs string) {
	var err error
	evidenceId := fileEvidence.Id
	// 定义一个重试策略
	retryStrategy := []retry.Option{
		retry.Delay(10 * time.Millisecond),
		retry.Attempts(2),
		retry.LastErrorOnly(true),
	}
	// 使用重试策略进行重试
	log.Infof("%s's putDataEvidence is : %v", evidenceId, putValue)
	err = retry.Do(
		func() error {
			txId, payload := client.PutDataEvidence(evidenceId, putValue)
			log.Infof("txId: %s, payload: %s", txId, payload)
			t1, err := strconv.ParseBool(gjson.Get(payload, "success").Raw)
			if err != nil {
				log.Errorf("payload获取success字段值 err is : %v: ", err)
			}
			if t1 {
				txInfo := client.GetTransactionInfoById(txId)
				blockInfo := client.GetBlockInfoById(txId)

				letterParam := is.GetDepositoryLetterParam(fileEvidence.UserId)
				letterParam.EvidenceId = fileEvidence.Id
				letterParam.TxId = txInfo.TxId
				letterParam.EvidenceTime = txInfo.TxTime
				letterParam.BlockNum = int(blockInfo.BlockNum)
				letterParam.BlockHash = blockInfo.BlockHash
				letterParam.FileHash = hashs
				tempDir := os.TempDir()
				path := utils.StrJoin(tempDir, constant.FileSeparator, evidenceId, constant.FileSeparator, "存证函.png")
				letterParam.TargetFile = path
				err := utils.CreateEvidenceLetter(letterParam)
				if err != nil {
					log.Errorf("create evidence letter error: %v", err)
					return err
				}

				fileUrl, err := upload.GetUploadClient().UploadFile(path, letterParam.EvidenceId+"/存证函.png")
				if err != nil {
					log.Errorf("fileEvidenceToChain upload file error: %v", err)
					return err
				}
				file.DeleteFile(path)

				fileEvidence.TxId = txId
				fileEvidence.TxTime = txInfo.TxTime
				fileEvidence.EvidenceCert = fileUrl
				fileEvidence.Status = "1"
				fileEvidence.UpdatedTime = time.Now()
				_, err = is.DbEngine.Where("id = ?", evidenceId).Cols("evidence_cert", "tx_id", "tx_time", "status", "updated_time").Update(&fileEvidence)
				if err != nil {
					log.Errorf("%s 更新文件存证 eror %v:  ", evidenceId, err)
					return err
				}
			}
			return err
		},
		retryStrategy...)

	if err != nil {
		log.Errorf("Error occurred after 2 retries")
		fileEvidence.Status = "2"
		fileEvidence.UpdatedTime = time.Now()
		_, err = is.DbEngine.Where("id = ?", evidenceId).Cols("status", "updated_time").Update(&fileEvidence)
		if err != nil {
			log.Errorf("%s 更新文件存证 eror %v:  ", err)
			return
		}
	}
}
